package com.neuronbit.businessflow.flow.source;

import com.neuronbit.businessflow.flow.parser.FlowNode;
import com.neuronbit.businessflow.flow.project.Project;
import com.neuronbit.businessflow.flow.source.util.FieldBuilder;
import com.neuronbit.businessflow.flow.source.util.Imports;
import com.neuronbit.businessflow.intellij.model.Param;
import com.neuronbit.businessflow.intellij.model.SimpleType;
import com.neuronbit.javaparser.ast.CompilationUnit;
import com.neuronbit.javaparser.ast.Modifier;
import com.neuronbit.javaparser.ast.body.ClassOrInterfaceDeclaration;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;

import static org.apache.commons.lang3.StringUtils.uncapitalize;

/**
 * The type Flow param java source.
 */
public class FlowParamJavaSource implements JavaSource {

    private CompilationUnit cu;
    private String flowParamClassName;

    /**
     * Instantiates a new Flow param java source.
     *
     * @param flow          the flow
     * @param contextSource the context source
     * @param packageName   the package name
     * @param project       the project
     */
    public FlowParamJavaSource(FlowNode flow, ContextJavaSource contextSource, String packageName, Project project) {
        ClassOrInterfaceDeclaration flowParamClass;
        flowParamClassName = null;
        if (MapUtils.isNotEmpty(flow.getCallable().getParams())) {
            cu = new CompilationUnit(packageName);
            flowParamClass = cu.addClass(flow.getInputClassName());
            flowParamClassName = flowParamClass.getNameAsString();
            flowParamClass.setFinal(true);
            flowParamClass.setModifiers(Modifier.Keyword.PUBLIC);
            for (Param input : flow.getCallable().getParams().values()) {
                Imports.of(input.getType()).install(cu);
                FieldBuilder.builder(input.getName(), input.getType())
                        .withSetter()
                        .withGetter()
                        .buildInto(flowParamClass);
            }


            FieldBuilder fieldBuilder = FieldBuilder.builder(uncapitalize(flowParamClassName), SimpleType.of(flowParamClassName))
                    .withGetter()
                    .withSetter();
            contextSource.addField(fieldBuilder);
        }
    }

    @Override
    public void generate() throws ClassNotFoundException, NoSuchMethodException {

    }

    @Override
    public CompilationUnit getCompilationUnit() {
        return cu;
    }

    @Override
    public String getFileName() {
        return flowParamClassName;
    }

    /**
     * Gets simple name.
     *
     * @return the simple name
     */
    public String getSimpleName() {
        return flowParamClassName;
    }
}
